package vo;

import util.INumberRange;

import java.util.ArrayList;

/**
 * @author 螺旋仓颉
 * 数独用格子类
 */
public class Grid implements INumberRange {
    /**
     * 格子所在行
     */
    private int row;

    /**
     * 格子所在列
     */
    private int column;

    /**
     * 格子所在大区域
     */
    private String range;

    /**
     * 格子是否已确定
     */
    private boolean ensure;

    /**
     * 可能存在的数字
     */
    private ArrayList<String> possibleNum = new ArrayList<>();

    /**
     * 目前的数字
     */
    private String presentNum;

    public void setRow(int row) {
        if (ROW_RANGE.contains(row)) {
            this.row = row;
            //在设置行时尝试判断所属区域
            if (COLUMN_RANGE.contains(this.column)) {
                this.setRange();
            }
        }
    }

    public void setColumn(int column) {
        if (COLUMN_RANGE.contains(column)) {
            this.column = column;
            //在设置列时尝试判断所属区域
            if (ROW_RANGE.contains(this.row)) {
                this.setRange();
            }
        }
    }

    /**
     * 根据输入的数字判断该格子是否已经确定
     */
    private void setEnsure() {
        this.ensure = NUMBER_RANGE.contains(this.presentNum);
    }

    public void setPossibleNum(ArrayList<String> possibleNum) {
        this.possibleNum = possibleNum;
    }

    public void setPresentNum(String presentNum) {
        this.presentNum = presentNum;
        //在输入格子代表的数字时判断该格子是否确定
        this.setEnsure();
    }

    public int getRow() {
        return row;
    }

    public int getColumn() {
        return column;
    }

    public String getRange() {
        return range;
    }

    public boolean isEnsure() {
        return ensure;
    }

    public ArrayList<String> getPossibleNum() {
        return possibleNum;
    }

    public String getPresentNum() {
        return presentNum;
    }

    /**
     * 根据格子所在行列判断格子所在的大区
     */
    private void setRange() {
        this.range = ROW_RANGE_MAP.get(this.row) + COLUMN_RANGE_MAP.get(this.column);
    }

    /**
     * 根据可能性个数刷新格子，当可能性为0时返回false，当可能性为1时填入数字
     */
    public boolean refresh() {
        int num = this.possibleNum.size();
        switch (num) {
            case 0: {
                return false;
            }
            case 1: {
                this.setPresentNum(this.possibleNum.get(0));
                return true;
            }
            default:
                return true;
        }
    }
}
